# CBV版添加班级
import hashlib
import json
import re
from datetime import datetime

from Django_Admin.enumType import EnvType
from Manager.views.service import my_page
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.http import JsonResponse, HttpResponse, HttpResponseRedirect
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import View
from django.views.decorators.csrf import csrf_exempt

from Django_Admin import settings
from Rbac.models import Role, Menu, Permission, Environment, Customer
from Rbac.service.init_permission import init_permission

from Django_Admin.enumType import IsActive_choices
from Rbac.utils.encrypt import encryptPassword
from Rbac.utils.decode import decryptPassword
from Manager.models import *
from Rbac.utils.login_deco import *
from django.db.models import Q
import datetime


# 用户登录
class loginClass(View):
    def __init__(self):

        self.result = {'code': 201, 'message': '请输入用户名和密码'}

    # 获取login页面时调用
    def get(self, request):
        return render(request, "user/login.html", locals())

    # 输入用户名密码后点击验证按钮时调用
    def post(self, request):
        _username = request.POST['username']
        _password = request.POST['password']
        # print(_username)
        user = Customer.objects.filter(customerid=_username).first()
        islogin = Customer.objects.filter(customerid=_username).filter(roles__permissions__isOnly=1)
        if user is None:
            self.result['message'] = '用户名不存在或密码错误'
        else:
            if user.isactive == 0:
                self.result['message'] = '当前帐户已被禁用'
            if not bool(islogin):
                self.result["message"] = "当前用户无登录权限"
            else:
                # 去用户名相同的所有密码，密码解密后做判断
                pwd_vqs = Customer.objects.filter(customerid=_username).values_list('customerid', 'password')
                # print('pwd_vqs:', pwd_vqs)
                _user = None
                for item in pwd_vqs:
                    # 用户名是主键， 不必去重
                    name = list(item)[0]
                    encrypt_pwd = list(item)[1]
                    decrypt_pwd = decryptPassword(encrypt_pwd)
                    if _username == name and _password == decrypt_pwd:
                        # 登录成功
                        try:
                            _user = Customer.objects.filter(customerid=name).first()
                            request.session['islogin'] = True
                            request.session['id'] = _user.customerid
                            request.session['acc'] = _user.customername
                            request.session['name'] = _user.customername
                            # session过期时间
                            # request.session.set_expiry(0)
                            init_permission(request, _user)  # 登录之后对用户的角色权限做一个初始化，存放在session中
                            return redirect('/rbac/users/')
                        except Exception as e:
                            self.result['code'] = 500
                            self.result['message'] = e
                            return render(request, "user/login.html", locals())
                if _user is None:
                    self.result['message'] = '用户名不存在或密码错误'
        return render(request, "user/login.html", locals())


# 用户退出
class signout(View):
    # 点击用户头像中推出按钮时调用
    def get(self, request):
        request.session['islogin'] = False
        request.session['id'] = -1
        request.session['name'] = ''
        request.session[settings.SESSION_PERMISSION_URL_KEY] = None
        request.session[settings.SESSION_MENU_KEY] = None
        return HttpResponseRedirect('/')


class main(View):
    def get(self, request):
        return render(request, "user/main.html")

    def post(self, request):
        return render(request, "user/main.html")


# 修改密码
class modifyPwd(View):
    def __init__(self):
        self.result = {'code': 201, 'message': '密码修改成功,下次登录请使用新密码！'}

    # 点击用户头像中修改密码按钮后输入新密码后点击确认按钮时调用
    def post(self, request):
        id = request.session['id']
        oldPwd = request.POST['oldPwd']
        newPwd1 = request.POST['newPwd1']
        newPwd2 = request.POST['newPwd2']
        try:
            _user = Customer.objects.get(customerid=id)

            if decryptPassword(_user.password) != oldPwd:
                self.result['message'] = '原密码输入不正确'
                # print('原密码输入不正确')
            elif newPwd1 != newPwd2:
                self.result['message'] = '两次密码输入不相同'
                # print('两次密码输入不相同')
            else:
                _user.password = encryptPassword(newPwd1)
                _user.save()
                # print('保存成功')
        except:
            self.result['code'] = 500
            self.result['message'] = '服务器内部错误'
        return JsonResponse(self.result, safe=False)


@auth
# 用户列表
def userList(request):
    off = request.GET.get('offset', None)
    lim = request.GET.get('limit', None)
    search = request.GET.get('search', None)
    if search is None:
        return render(request, "rbac/users.html")
    else:
        if search:
            userList = Customer.objects.values().filter(customername__contains=search)
        else:
            userList = Customer.objects.values()
    userList = list(userList)
    for userinfo in userList:
        userinfo['option'] = userinfo['customerid']
        userinfo['isactive'] = IsActive_choices[userinfo['isactive']]
        # userobj = Customer.objects.get(customerid=userinfo['customerid'])
        # userinfo['roles'] = list(userobj.roles.all().values("title"))[0].get("title") if userobj.roles.all() else ""
    result = my_page(userList, lim, off)
    # print(result)
    return JsonResponse(result, safe=False)


# 用户增删改查
def user_modify(request):
    ##拿到登录用户id
    userid = request.session["id"]
    ##查看用户是否有的权限
    isdelete = Customer.objects.filter(customerid=userid).filter(roles__permissions__url__endswith='users(delete)')
    ismodify = Customer.objects.filter(customerid=userid).filter(roles__permissions__url__endswith='users(modify)')
    isadd = Customer.objects.filter(customerid=userid).filter(roles__permissions__url__endswith='users(add)')
    if request.method == "GET":
        customer_id = request.GET["customerid"]
        item = Customer.objects.filter(customerid=customer_id).values().first()
        userobj = Customer.objects.get(customerid=customer_id)
        if item:
            row = {
                'customerid': item['customerid'],
                'customername': item['customername'],
                'password': item['password'],
                'confirmpwd': "",
                "isactive": IsActive_choices.get(item['isactive']),
                'maxlogined': item['maxlogined'],
                # 'roles': list(userobj.roles.all().values("title"))[0].get("title") if userobj.roles.all() else ""
            }
            return JsonResponse(row, safe=False)
    else:
        if request.POST.get('delete', None):
            ##有权限则进行操作
            if isdelete:
                CustomerID = request.POST.get('id')
                # print('被删除的用户的', CustomerID)
                # Customer.objects.filter(customerid=CustomerID).delete()
                # 判断其他表是否在使用customerid，如果在使用，提示用户先删除其他表的记录；如果没有，删除
                # Rule，CustomerRuleRel，CustomerChannelRel，Role
                rule_count = Rule.objects.filter(customerid=CustomerID).count()
                customerrulerel_count = Customerrulerel.objects.filter(customerid=CustomerID).count()
                customerchannelrel_count = Customerchannelrel.objects.filter(customerid=CustomerID).count()
                role_count = Role.objects.filter(customer__customerid=CustomerID).count()
                # print(role_count)
                deletemsg = ""
                if rule_count >= 1:
                    deletemsg = '用户有关联策略！'
                # if customerrulerel_count >= 1:
                #     deletemsg = '策略配对表有在使用此用户，请先删除使用此策略配对！'
                if customerchannelrel_count >= 1:
                    deletemsg = '用户有关联分账户！'
                # if role_count >= 1:
                #     deletemsg = '角色在使用此用户，请先删除使用此用户的角色！'
                # 没有其他表引用customerid，可以删除
                if len(deletemsg) == 0:
                    Customer.objects.filter(customerid=CustomerID).delete()
                    return HttpResponse('y')
                else:
                    # print(deletemsg)
                    return HttpResponse(deletemsg)
                # return HttpResponse('y')
            else:
                return HttpResponse("当前用户无该操作权限!")
        else:
            data = request.POST
            # 是修改操作
            if Customer.objects.filter(customerid=json.loads(data['customerid'])[0]).count() >= 1:
                ##有修改权限
                if ismodify:
                    customerobj = Customer.objects.get(customerid=json.loads(data["customerid"])[0])
                    customerobj.customername = json.loads(data['customername'])[0]
                    # customerobj.isactive = 1 if json.loads(data['isactive'])[0] == "是" else 0
                    customerobj.updatetime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                    customerobj.maxlogined = json.loads(data['maxlogined'])[0]
                    customerobj.save()
                    return HttpResponse('y')
                else:
                    return HttpResponse("当前用户无该操作权限！")
            # 是新增操作
            else:
                if isadd:
                    if json.loads(data['password'])[0] == json.loads(data['confirmpwd'])[0]:
                        if json.loads(data['ismd5'])[0] == False:
                            Customer.objects.create(
                                customerid=json.loads(data['customerid'])[0],
                                customername=json.loads(data['customername'])[0],
                                password=encryptPassword(json.loads(data['password'])[0]),
                                isactive=1 if json.loads(data['isactive'])[0] == "是" else 0,
                                maxlogined=int(json.loads(data['maxlogined'])[0]),
                                createtime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                                updatetime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                            )
                        else:
                            Customer.objects.create(
                                customerid=json.loads(data['customerid'])[0],
                                customername=json.loads(data['customername'])[0],
                                password=json.loads(data['password'])[0],
                                isactive=1 if json.loads(data['isactive'])[0] == "是" else 0,
                                maxlogined=json.loads(data['maxlogined'])[0],
                                createtime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                                updatetime=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                            )
                        # role = json.loads(data['roles'])[0]
                        # addUserRole = Role.objects.get(title=role)
                        # addUser.roles.add(addUserRole)
                        return HttpResponse('y')
                    else:
                        return HttpResponse("两次密码输入不一致")
                else:
                    return HttpResponse("当前用户无该操作权限")
    return render(request, 'rbac/users.html')


# 用户查询活跃状态
def activestatus(request):
    customerid = request.POST.get("id")
    try:
        customerobj = Customer.objects.get(customerid=customerid)
        activepara = customerobj.isactive
        customerobj.isactive = 1 if activepara == 0 else 0
        customerobj.save()
        return HttpResponse("y")
    except Exception as e:
        # print(e)
        return HttpResponse(e)


# 重置密码
def inipwd(request):
    customerid = request.POST.get("id")
    ismd5 = request.POST.get("ismd5")
    npwd = request.POST.get("npwd")
    try:
        customerobj = Customer.objects.get(customerid=customerid)
        if ismd5 == 'true':
            customerobj.password = npwd
        else:
            customerobj.password = encryptPassword(npwd)
        customerobj.save()
        return HttpResponse("y")
    except Exception as e:
        # print(e)
        return HttpResponse(e)


# 角色列表
@auth
def roleList(request):
    off = request.GET.get('offset', None)
    lim = request.GET.get('limit', None)
    search = request.GET.get('search', None)
    if search is None:
        return render(request, "rbac/roles.html")
    else:
        if search:
            roleList = Role.objects.values().filter(title__contains=search)
        else:
            roleList = Role.objects.values()
    roleList = list(roleList)
    for roleinfo in roleList:
        roleinfo['option'] = roleinfo['id']
    result = my_page(roleList, lim, off)
    # print(result)
    return JsonResponse(result, safe=False)


# 角色增删改查
def roles_modify(request):
    ##拿到登录用户id
    userid = request.session["id"]
    isdelete = Customer.objects.filter(customerid=userid).filter(roles__permissions__url__endswith='roles(delete)')
    ismodify = Customer.objects.filter(customerid=userid).filter(roles__permissions__url__endswith='roles(modify)')
    isadd = Customer.objects.filter(customerid=userid).filter(roles__permissions__url__endswith='roles(modify)')
    if request.method == "GET":
        rid = request.GET["id"]
        item = Role.objects.filter(id=rid).values().first()
        if item:
            row = {
                'id': item['id'],
                'rolename': item['title'],
            }
            return JsonResponse(row, safe=False)
    else:
        if request.POST.get('delete', None):
            if isdelete:
                rid = request.POST.get('id')
                customerobj = Customer.objects.filter(roles__id=rid).all()
                if customerobj:
                    return HttpResponse("请先删除该角色关联的用户！")
                else:
                    roleobj = Role.objects.get(id=rid)
                    roleobj.permissions = ""
                    roleobj.delete()
                    return HttpResponse('y')
            else:
                return HttpResponse("该用户无操作权限！")
        else:
            data = request.POST
            roleid = json.loads(data['id'])
            if roleid:
                if ismodify:
                    roleobj = Role.objects.get(id=json.loads(data["id"])[0])
                    roleobj.title = json.loads(data['title'])[0]
                    roleobj.save()
                    return HttpResponse('y')
                else:
                    return HttpResponse("该用户无操作权限!")
            else:
                if isadd:
                    roleobj = Role()
                    roleobj.title = json.loads(data['title'])[0]
                    roleobj.save()
                    return HttpResponse('y')
                else:
                    return HttpResponse("该用户无操作权限!")
    return render(request, 'rbac/roles.html')


# 权限列表
@auth
def permissionList(request):
    customerobj = Customer.objects.all()
    roleobj = Role.objects.all()
    # 取出所有menu_id不是空的permission(其实就是菜单，只不过存在权限表中了)
    permissionbj = Permission.objects.filter(menu_id__gt=0).values()
    # 取出所有menu_id为空的permissions(菜单对应的增删改权限)
    permissionbj2 = Permission.objects.filter(menu_id=None).values()
    print(list(permissionbj2)[10:])
    l = []
    # 遍历菜单列表，
    for pm in permissionbj:
        # 字典用于保存 菜单（key）和对应的权限（value）
        rp_in = {}
        permissonlist = []
        # 遍历权限列表，
        for p in permissionbj2:
            # 增删改的url是在对应菜单的url基础上做的拼接，如果符合，则保存在权限列表中，否则执行下一次循环
            if p.get("url").startswith(pm.get("url")) and pm.get('name') != "策略管理":
                permissonlist.append(p.get("name"))
            else:
                continue
        if permissonlist:  # 权限列表不为空，则加入字典中
            rp_in[pm.get("name")] = permissonlist  # 保存在菜单权限字典中
            l.append(rp_in)  # 字典放到大列表中
        # else:
    perm_mag = l[:3]  # 权限管理及其对应的权限
    adm_mag = l[3:]  # 系统管理及其对应的权限
    # print(perm_mag)
    # print(adm_mag)
    return render(request, 'rbac/permissions.html',
                  {'cobj': customerobj, 'robj': roleobj, 'perm_mag_list': perm_mag, 'adm_mag_list': adm_mag})


# 增删改(用户对应的角色，权限)
def permission_modify(request):
    ##拿到登录用户id
    userid = request.session["id"]
    isdelete = Customer.objects.filter(customerid=userid).filter(roles__permissions__url__endswith='permission(delete)')
    ismodify = Customer.objects.filter(customerid=userid).filter(roles__permissions__url__endswith='permission(modify)')
    isadd = Customer.objects.filter(customerid=userid).filter(roles__permissions__url__endswith='permission(add)')
    if request.method == "GET":
        flag = request.GET['flag']
        id = request.GET['id']
        # 点击的是用户
        if flag == "user":
            role_list = []
            roles = Customer.objects.filter(customerid=id).values("roles")
            roles = list(roles)
            for dic in roles:
                role_list.append(dic.get("roles"))
            # print(role_list)
            return JsonResponse(role_list, safe=False)
            # return render(request, 'rbac/permissions.html', {'role_list': role_list})
        else:
            permission_list = []
            # 只把权限部分，即menu_id为空的筛选出来
            # permissions = Role.objects.filter(id=id).filter(permissions__menu_id=None).values("permissions__name")
            # 把所有的权限都找出来
            # permissions = Role.objects.filter(id=id).values("permissions__name")
            permissions = Role.objects.filter(id=id).values("permissions__name")
            # print(permissions)
            permissions = list(permissions)
            for dic in permissions:
                permission_list.append(dic.get('permissions__name'))
            return JsonResponse(permission_list, safe=False)
    else:
        # post请求
        data = request.POST
        custid = data['id']

        if ismodify or isadd or isdelete:
            # 修改用户的角色
            if custid and Customer.objects.filter(customerid=custid).count() >= 1:
                roles = json.loads(data['role'])
                cobj = Customer.objects.get(customerid=custid)
                # 角色复选框不是空
                if roles:
                    rolesobj = Role.objects.filter(id__in=roles)
                    cobj.roles = rolesobj
                else:
                    cobj.roles = ""
                cobj.save()
            else:
                robj = Role.objects.get(id=custid)
                permissions = json.loads(data['perm'])
                # 以下是左侧菜单，也对应的是权限，因为是直接赋值式新增，所以需要初始化加上，
                # 否则登录之后左侧菜单就会消失
                # for i in ["用户列表","角色列表","权限列表","实体账户","分账户管理","策略配对管理",
                #     "MAC地址白名单","策略限仓管理","用户策略管理","数据库信息维护","合约做市参数"]:
                #     permissions.append(i)
                if permissions:
                    perobj = Permission.objects.filter(name__in=permissions)
                    robj.permissions = perobj
                else:
                    robj.permissions = ""
                robj.save()
            return HttpResponse('y')
        else:
            return HttpResponse("该用户无操作权限！")
    return render(request, 'rbac/permissions.html')


# sha256加密算法
def sha256(msg):
    hash = hashlib.sha256()
    hash.update(msg.encode('utf-8'))
    return hash.hexdigest()
